﻿Imports Microsoft.Practices.EnterpriseLibrary.Data
Imports System.Configuration
Imports System.Collections.Specialized
Imports System.Text
Imports System.Xml.Serialization
Imports System.IO
Imports System.Collections
Imports ExchangeUSE.Contract

Public Class Main
    Private AppSettingList As List(Of TableInfo) = New List(Of TableInfo)
    Private TableList As List(Of TableInfo) = New List(Of TableInfo)
    Private CurrentSel As TableInfo
    Private db As Database = Nothing
    Private DataType As Type
    Private isDecryption As Boolean = False
    Private Sub Main_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load

        Me.TableComboDataInit()
        Dim lstDBConn As List(Of DBConnctionString)
        Dim objDBConn As DBConnctionString
        lstDBConn = New List(Of DBConnctionString)
        objDBConn = New DBConnctionString
        objDBConn.name = "Sql Server"
        objDBConn.providerName = "System.Data.SqlClient"
        objDBConn.defaultDataSource = "localhost"
        objDBConn.connectionString = "Data Source=[%1];User Id=[%2];Password=[%2];Initial Catalog=[%2];"
        lstDBConn.Add(objDBConn)
        objDBConn = New DBConnctionString
        objDBConn.name = "Oracle"
        objDBConn.providerName = "System.Data.OracleClient"
        objDBConn.defaultDataSource = "localhost/USE_WF"
        objDBConn.connectionString = "Data Source=[%1];User Id=[%2];Password=[%2];"
        lstDBConn.Add(objDBConn)
        objDBConn = New DBConnctionString
        objDBConn.name = "Access"
        objDBConn.providerName = "System.Data.OleDb"
        objDBConn.defaultDataSource = ""
        objDBConn.connectionString = "Provider=Microsoft.Jet.OLEDB.4.0;Data Source=[%1];"
        lstDBConn.Add(objDBConn)
        cmbDBType.DisplayMember = "name"
        cmbDBType.DataSource = lstDBConn

        cmbDBType.SelectedIndex = 0

        tboxDataBase.Text = "USE_WF"

    End Sub

    Private Sub ComboBoxTable_SelectedIndexChanged(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles ComboBoxTable.SelectedIndexChanged
        Dim selectIndex As Integer = ComboBoxTable.SelectedIndex

        If (selectIndex >= 0) Then
            TextBoxName.Text = TableList.Item(selectIndex).keyName
            TextBoxValue.Text = TableList.Item(selectIndex).keyValue
            TextBoxBinary.Text = TableList.Item(selectIndex).binaryKey

            CurrentSel = TableList.Item(selectIndex)
            For Each item In cmbEncoding.Items
                If item.Equals(CurrentSel.EncodingName) Then
                    cmbEncoding.SelectedItem = item
                End If
            Next
            tboxDataBase.Text = TableList.Item(selectIndex).DataBaseName
        End If

    End Sub


    Private Sub ButtonRecovery_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles ButtonRecovery.Click
        '更新は利用可
        isDecryption = False
        btnUpdate.Enabled = True

        CurrentSel = SetSearchCondition()
        db = GetDBConnction()
        If db Is Nothing Then
            Exit Sub
        End If

        If Recovery(CurrentSel) = True Then
            saveToConfig(CurrentSel)
            
        End If

    End Sub
    Private Function SetSearchCondition() As TableInfo
        Dim CurrentSel As New TableInfo
        CurrentSel.keyValue = TextBoxValue.Text
        CurrentSel.binaryKey = TextBoxBinary.Text
        CurrentSel.keyName = TextBoxName.Text
        CurrentSel.tableName = ComboBoxTable.Text
        CurrentSel.keyValue = TextBoxValue.Text
        CurrentSel.binaryKey = TextBoxBinary.Text
        CurrentSel.keyName = TextBoxName.Text
        Return CurrentSel
    End Function
    Private Sub saveToConfig(ByVal currentSel As TableInfo)
        Try

            Dim SettingQuery = From obj In AppSettingList
                                   Where obj.tableName = currentSel.tableName And obj.keyName = currentSel.keyName _
                                   And obj.binaryKey = currentSel.binaryKey
            If SettingQuery.Count = 0 Then
                currentSel.DataBaseName = tboxDataBase.Text
                currentSel.EncodingName = cmbEncoding.Text

                '①テーブルの名前±②主キーの名前±③主キーのValue±④バイナリキー±⑤Encoding情報±⑤DB情報’
                Dim config As Configuration


                config = ConfigurationManager.OpenExeConfiguration(ConfigurationUserLevel.None)
                Dim appSettingSection As AppSettingsSection = config.AppSettings
                appSettingSection.Settings.Add("table[" & ConfigurationManager.AppSettings.Count & "]", _
                                                    currentSel.tableName & "±" & _
                                                    currentSel.keyName & "±" & _
                                                    "" & "±" & _
                                                    currentSel.binaryKey & "±" & _
                                                    currentSel.EncodingName & "±" & _
                                                    currentSel.DataBaseName)

                config.Save(ConfigurationSaveMode.Full)
                ConfigurationManager.RefreshSection("AppSettings")
                TableComboDataInit()
            End If

        Catch ex As Exception
            MsgBox(ex.Message)
        End Try
    End Sub
    Private Sub TableComboDataInit()
        TableList.Clear()
        AppSettingList.Clear()
        Dim tableItem As TableInfo
        Dim config As Configuration
        config = ConfigurationManager.OpenExeConfiguration(ConfigurationUserLevel.PerUserRoamingAndLocal)
        Dim appSettingSection As AppSettingsSection = config.AppSettings

        Dim tableCount As Integer = appSettingSection.Settings.Count

        For Each key As String In appSettingSection.Settings.AllKeys


            Dim cfgvalue As String = appSettingSection.Settings.Item(key).Value
            Dim valueArray As String()

            If key.Length >= 5 And "table".Equals(key.Substring(0, 5)) Then
                valueArray = cfgvalue.Split("±")
                tableItem = New TableInfo(valueArray(0), valueArray(1), valueArray(2), valueArray(3))
                If valueArray.Length >= 5 AndAlso Not String.IsNullOrEmpty(valueArray(4)) Then
                    tableItem.EncodingName = valueArray(4).ToUpper
                End If
                If valueArray.Length >= 6 AndAlso Not String.IsNullOrEmpty(valueArray(5)) Then
                    tableItem.DataBaseName = valueArray(5).ToUpper
                End If
                TableList.Add(tableItem)
                AppSettingList.Add(tableItem)
            End If
        Next

        TableList.Insert(0, New TableInfo("", "", "", ""))

        ComboBoxTable.DataSource = Nothing

        ComboBoxTable.DisplayMember = "tableName"
        ComboBoxTable.DataSource = TableList

    End Sub

    Private Function Recovery(ByVal tableInfo As TableInfo) As Boolean
        Dim RecoveryController As Controller = New Controller
        Dim binaryData As Object = Nothing
        Dim result As Boolean = True
        db = GetDBConnction()
        If db Is Nothing Then
            Return False
        End If
        Dim recoveryContent As String = Nothing
        Dim utf8Encoding As New System.Text.UTF8Encoding
        Dim shiftJisEncoding As System.Text.Encoding
        binaryData = RecoveryController.GetData(db, tableInfo)
        If binaryData Is Nothing Then
            Return False
        End If
        If IsDBNull(binaryData) Then
            recoveryContent = ""
            '更新は利用不可
            isDecryption = True
            btnUpdate.Enabled = False
        Else
            DataType = binaryData.GetType
            If binaryData.GetType.Name = "Byte[]" Then
                If cmbEncoding.SelectedItem = "UTF-8" Then
                    recoveryContent = utf8Encoding.GetString(binaryData)
                Else
                    shiftJisEncoding = Encoding.GetEncoding(cmbEncoding.SelectedItem)
                    recoveryContent = shiftJisEncoding.GetString(binaryData)
                End If
            Else
                recoveryContent = binaryData
            End If
        End If
        
        tboxContent.ResetText()
        tboxContent.Text = recoveryContent
        Return result
    End Function

    Private Function GetDBConnction() As Database
        If String.IsNullOrEmpty(Trim(txtDateSource.Text)) Then
            MsgBox("データソースを入力してください。")
        Else
            Dim selectedDBConnctionString As DBConnctionString = CType(cmbDBType.SelectedItem, DBConnctionString)
            Dim provider As System.Data.Common.DbProviderFactory = _
               System.Data.Common.DbProviderFactories.GetFactory(selectedDBConnctionString.providerName)
            Dim dtSource As String = txtDateSource.Text
            If chkAllConnStr.Checked = True Then
                db = New GenericDatabase(dtSource, provider)
            Else
                Dim dbConnString As String
                dbConnString = selectedDBConnctionString.connectionString
                dbConnString = Replace(selectedDBConnctionString.connectionString, "[%1]", dtSource)
                If String.IsNullOrEmpty(tboxDataBase.Text) Then
                    dbConnString = Replace(dbConnString, "[%2]", "USE_WF")
                Else
                    dbConnString = Replace(dbConnString, "[%2]", tboxDataBase.Text)
                End If

                db = New GenericDatabase(dbConnString, provider)
            End If
            Return db
        End If
        Return Nothing
    End Function

    Private Sub cmbDBType_SelectedIndexChanged(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles cmbDBType.SelectedIndexChanged
        Dim selectedDBConnctionString As DBConnctionString = CType(cmbDBType.SelectedItem, DBConnctionString)
        txtDateSource.Text = selectedDBConnctionString.defaultDataSource
    End Sub

    Private Sub BtnDecryption_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles BtnDecryption.Click
        Dim RecoveryController As Controller = New Controller
        Dim binaryData As Object = Nothing
        Dim strParamaterXml As String

        CurrentSel = SetSearchCondition()

        'データベースアクセス
        db = GetDBConnction()

        If db Is Nothing Then
            Exit Sub
        End If
        binaryData = RecoveryController.GetData(db, CurrentSel)
        If binaryData Is Nothing Then
            Exit Sub
        End If
        Dim selectedDBConnctionString As DBConnctionString = CType(cmbDBType.SelectedItem, DBConnctionString)

        If selectedDBConnctionString.providerName = "System.Data.OracleClient" Then
            strParamaterXml = Encoding.UTF8.GetString(CType(binaryData, Byte()))
        Else
            strParamaterXml = binaryData.ToString()
        End If

        Dim paramXML As String = Nothing
        Dim ParameterCollection As SerializableDictionary(Of String, Object)
        Dim serializer As XmlSerializer = New XmlSerializer(GetType(SerializableDictionary(Of String, Object)))
        Dim ms As MemoryStream = New MemoryStream(System.Text.Encoding.UTF8.GetBytes(strParamaterXml))
        If Not String.IsNullOrEmpty(strParamaterXml) Then
            Dim objXmlDoc As New Xml.XmlDocument
            objXmlDoc.LoadXml(strParamaterXml)

            ParameterCollection = CType(serializer.Deserialize(ms), SerializableDictionary(Of String, Object))

            Dim ChgParamCollection As New SerializableDic(Of String, Object)
            Dim ser = New ExchangeUSE.Common.Serialize.RapidUSEXmlSerializer()
            For Each obj In ParameterCollection
                paramXML = ser.Serialize(obj.Value)
                ChgParamCollection.Add(obj.Key, paramXML)
            Next
            Dim XMLserializer As XmlSerializer = New XmlSerializer(GetType(SerializableDic(Of String, Object)))
            Using memoryStream = New MemoryStream
                XMLserializer.Serialize(memoryStream, ChgParamCollection)
                paramXML = Encoding.UTF8.GetString(memoryStream.ToArray)
                paramXML = paramXML.Replace("&lt;", "<")
                paramXML = paramXML.Replace("&gt;", ">")
            End Using
        End If
        tboxContent.ResetText()
        tboxContent.Text = paramXML
        '更新は利用不可
        isDecryption = True
        btnUpdate.Enabled = False
        saveToConfig(CurrentSel)
    End Sub

    Private Sub ButtonClose_Click_1(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles ButtonClose.Click
        Me.Close()
    End Sub

    Private Sub btnExport_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnExport.Click
        Dim RecoveryController As Controller = New Controller
        Dim binaryData As Object = Nothing
        '更新は利用可
        isDecryption = False
        btnUpdate.Enabled = True

        CurrentSel = SetSearchCondition()
        db = GetDBConnction()
        If db Is Nothing Then
            Exit Sub
        End If

        binaryData = RecoveryController.GetData(db, CurrentSel)
        If binaryData Is Nothing Then
            Exit Sub
        End If
        Me.SaveFileDialog.Filter = "全てファイル|*.*"
        Me.SaveFileDialog.FileName = Me.TextBoxValue.Text & ".xml"
        If (Me.SaveFileDialog.ShowDialog() = DialogResult.OK) Then
            RecoveryController.WriteFile(Me.SaveFileDialog.FileName, binaryData)
        End If

    End Sub

    Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnUpdate.Click

        Dim sContent As String
        Dim RecoveryController As Controller = New Controller
        'データベースアクセス
        db = GetDBConnction()

        If db Is Nothing Then
            Exit Sub
        End If

        If tboxContent.TextLength > 0 Then
            sContent = tboxContent.Text

            RecoveryController.UpdateData(db, CurrentSel, sContent, DataType, cmbEncoding.Text)
        End If
    End Sub

    Private Sub ToolStripMenuItem_Paste_Click(sender As System.Object, e As System.EventArgs) Handles ToolStripMenuItem_Paste.Click
        Me.tboxContent.Paste()
    End Sub

    Private Sub ToolStripMenuItem_Copy_Click(sender As System.Object, e As System.EventArgs) Handles ToolStripMenuItem_Copy.Click
        Me.tboxContent.Copy()
    End Sub

    Private Sub ToolStripMenuItem_Save_Click(sender As System.Object, e As System.EventArgs) Handles ToolStripMenuItem_Save.Click
        ' Me.tboxContent.SaveFile ()
    End Sub
End Class
Public Class DBConnctionString
    Public Property name As String
    Public Property connectionString As String
    Public Property providerName As String
    Public Property defaultDataSource As String
End Class
